import {
  Component,
  OnInit,
  Output,
  EventEmitter,
  Input,
  ViewChildren,
  QueryList,
  AfterViewInit,
  ElementRef,
  ViewChild,
  Renderer2
} from "@angular/core";
import {DomSanitizer} from "@angular/platform-browser";
import { ChangeDetectorRef } from "@angular/core";

@Component({
  selector: 'number-slider',
  templateUrl: './number-slider.component.html'
})

export class NumberSliderComponent {
  ionicDate: string;
  isStop: boolean;
  valuePadding: string;
  numberCollect: Array<number|string> = [];
  originData = 21345432.3;
  resultData: {
    resultNumbers: Array<string>,
    transforms: Array<number>,
    speed: number,
    symbol: string,
    suffix: string,
    prefix: string
  };
  transforms: Array<number> = [];
  resultDatas: Array<any> = [];
  numberSliderClass: NumberSliderClass;
  lastTransforms: Array<any> = [];
  domTemplateDates: any;
  @ViewChildren('animateDom') animateDom: QueryList<ElementRef>;
  @ViewChild('wrap', {read: ElementRef}) wrap: ElementRef;

  constructor(
    private domSanitizer: DomSanitizer,
    private elementRef: ElementRef,
    private ref: ChangeDetectorRef,
    private render2: Renderer2
  ) {
    this.numberSliderClass = new NumberSliderClass({
      num : this.originData,
    });
    let tem = this.numberSliderClass.init();
    this.domTemplateDates = tem.resultNumbers.map((resultNumber) => {
      return {
        numberTemplates: NumberSliderClass.numberCollect,
        resultNumber: resultNumber,
        transforms: tem.transforms
      };
    });
    this.lastTransforms = tem.transforms;
    this.transforms = tem.transforms;
  }

  ngAfterViewInit() {
    this.animateDom.map((elementRef, index) => {
      setTimeout(() => {
        elementRef.nativeElement.style.transform = `translateY(${this.transforms[index]}px)`;
      }, 0);
    });

    this.animateDom.changes.subscribe((data) => {
      let transforms = this.transforms;
      data.map((elementRef, index) => {
        elementRef.nativeElement.style.transform = `translateY(${this.domTemplateDates[0].transforms[index]}px)`;
      });
      data.map((elementRef, index) => {
        setTimeout(() => {
          elementRef.nativeElement.style.transform = `translateY(${transforms[index]}px)`;
        }, 0);
      });
    });
  }

  charge() {
    let tem2 =  this.numberSliderClass.reset(Math.random() * 10000000);
    let transforms = JSON.parse(JSON.stringify(tem2.transforms));
    if (this.lastTransforms.length < tem2.transforms.length) {
      for (let i = 0; i < tem2.transforms.length - this.lastTransforms.length; i++) {
        this.lastTransforms.push(0);
      }
    }
    if (this.lastTransforms.length > tem2.transforms.length) {
      for (let i = 0; i < this.lastTransforms.length - tem2.transforms.length; i++) {
        this.lastTransforms.shift();
      }
    }
    this.domTemplateDates = tem2.resultNumbers.map((resultNumber) => {
      return {
        numberTemplates: NumberSliderClass.numberCollect,
        resultNumber: resultNumber,
        transforms: JSON.parse(JSON.stringify(this.lastTransforms))
      };
    });
    this.lastTransforms = transforms;
    this.transforms = transforms;
  }
}

export interface  NumberSliderInterface {
    speed?: number;
    num?: number;
    iniAnimate?: boolean;
    symbol?: string;
    dot?: number;
    suffix?: string;
    prefix?: string;
}

export class NumberSliderClass {
    static numberCollect: Array<number|string> = [];
    config: NumberSliderInterface = {
        speed : 1,
        num : 0,
        iniAnimate : true,
        symbol : ',',
        dot : 2,
        suffix: "",
        prefix: ""
      };
    constructor(data) {
      this.config = Object.assign(this.config, data);
      for (let i = 0; i < 10 ; i ++) {
        NumberSliderClass.numberCollect.push(i);
      }
      NumberSliderClass.numberCollect.push('.');
      NumberSliderClass.numberCollect.push(this.config.symbol);
    }

    init(): {
      resultNumbers: Array<string>,
      transforms: Array<number>,
      speed: number,
      symbol: string,
      suffix: string,
      prefix: string
    } {
      if (!this.verify()) {
        return;
      }
      let transforms: Array<number> = [];
      return {
        resultNumbers: this.stringToArray()
          .map((cell) => {
            switch (cell) {
              case "." : transforms.push(-400); break;
              case this.config.symbol : transforms.push(-440); break;
              default : transforms.push(40 * (parseInt(cell, 0)) * (-1));
            }
            return cell;
          }),
        transforms: transforms,
        speed: this.config.speed,
        symbol: this.config.symbol,
        suffix: this.config.suffix,
        prefix: this.config.prefix,
      };
    }

    reset(newNumber: number) {
      this.config.num = newNumber;
      return this.init();
    }

    executeAnimate() {

    }

    private verify(): boolean {
      if (typeof (this.config.num) === 'string') {
        console.warn("number-slider need a number");
        return false;
      } else {
        return true;
      }
    }

    private autoPrefix(obj: {
      transform?: string,
      transition?: string
    }) {
      let json = {};
      for (let key in obj) {
        let vendors = [ '-webkit-', '-moz-', '-ms-', '-o-'],
            transform,
            i = 0,
            l = vendors.length;
        for ( ; i < l; i++ ) {
          json[vendors[i] + key] = obj[key];
        }
      }
      return json;
    }

    private stringToArray(): Array<string> {
      return this.transformThousand().split("");
    }

    private transformThousand() {
      let splitDecimalPlacesArray: Array<string> = this.config.num.toFixed(this.config.dot)
        .split('.');
      splitDecimalPlacesArray[0] = splitDecimalPlacesArray[0].split("").reverse().join("")
        .replace(/(\d{3})+?/g, (item) => {
        return item + ",";
      }).replace(/,$/, "").split("").reverse().join("");
      return splitDecimalPlacesArray.join(".");
    }

}


